#pragma once
#include <sstream>

class Vector3d
{
public:
	Vector3d(double x,double y,double z)
	{
		this->x = x;
		this->y = y;
		this->z = z;
	}
	Vector3d(const Vector3d &other);
	Vector3d(){
		x = 0;
		y = 0;
		z = 0;
	}
	~Vector3d();


	double x;
	double y;
	double z;

	Vector3d& operator=(const Vector3d &other);
	Vector3d& operator+=(const Vector3d &other);
	Vector3d& operator-=(const Vector3d &other);
	Vector3d& operator/=(const Vector3d &other);
	Vector3d& operator*=(const Vector3d &other);

	Vector3d& operator+(const Vector3d &other);
	Vector3d& operator-(const Vector3d &other);
	Vector3d& operator/(const Vector3d &other);
	Vector3d& operator*(const Vector3d &other);

	Vector3d& operator+=(const double &other);
	Vector3d& operator-=(const double &other);
	Vector3d& operator/=(const double &other);
	Vector3d& operator*=(const double &other);

	Vector3d& operator+(const double &other);
	Vector3d& operator-(const double &other);
	Vector3d& operator/(const double &other);
	Vector3d& operator*(const double &other);

	bool operator==(const Vector3d &other);
	bool operator!=(const Vector3d &other);

	double dot(const Vector3d &other ) const {
		return (x * other.x) + (y * other.y) + (z * other.z);
	};

	void Normalize() {
		double n = 1 / (sqrt(x*x + y*y + z*z ));
		x *= n;
		y *= n;
		z *= n;
	};

	double magnitude()
	{
		return sqrt(x*x + y*y +z*z);
	}

	static double distance(const Vector3d &A ,const Vector3d &B ) {
	return sqrt( ((A.x - B.x) * (A.x - B.x)) + ((A.y - B.y) * (A.y - B.y)) + ((A.z - B.z) * (A.z - B.z)) );
    }

	static Vector3d randomVector() 
	{
		Vector3d ret(cos(static_cast<double>(rand() % 360)),cos(static_cast<double>(rand() % 360)),cos(static_cast<double>(rand() % 360)));
		ret.Normalize();
		return ret;
	};

	std::string print();
};


